package com.jcf.springboot.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jcf.springboot.entity.sys.Manager;
import com.jcf.springboot.entity.sys.Menu;
import com.jcf.springboot.entity.sys.SysRole;
import com.jcf.springboot.mapper.ManagerMapper;
import com.jcf.springboot.mapper.MenuMapper;
import com.jcf.springboot.mapper.SysRoleMapper;
import com.jcf.springboot.security.util.JwtUtil;
import com.jcf.springboot.service.ManagerService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author jjj
 * @since 2021-03-18
 */
@Slf4j
@Service
public class ManagerServiceImpl extends ServiceImpl<ManagerMapper, Manager> implements ManagerService {

  @Autowired
  private MenuServiceImpl menuService;
  @Autowired
  private MenuMapper menuMapper;
  @Autowired
  private SysRoleMapper roleMapper;
  @Autowired
  private ManagerMapper managerMapper;
  @Autowired
  private JwtUtil jwtUtil;
  @Autowired
  private StringRedisTemplate stringRedisTemplate;

  @Override
  public String getUserAuthorityInfo(String userId) {
    StringBuffer auth = new StringBuffer();
    List<SysRole> roleList = roleMapper.getRoleByUserId(userId);
    String collect = roleList.stream().map(e -> "ROLE_" + e.getCode()).collect(Collectors.joining(","));
    List<Menu> menuList = menuMapper.getByUserId(userId);
    auth.append(collect);
    if (menuList.size() > 0)
    {
      String collect1 = menuList.stream().map(Menu::getPerms).filter(Objects::nonNull).distinct().collect(Collectors.joining(","));
      auth.append(",");
      auth.append(collect1);

    }
    return auth.toString();
  }

  @Override
  public Map sealData(Manager one) {
    String username = one.getManagerName();

    String token = jwtUtil.generateToken(username);
//    一小段与程序无关的redis代码

    stringRedisTemplate.expire("login:user:" + token, 1800, TimeUnit.SECONDS);


    List<Menu> menuList = getMenuList(username);
    List<Menu> menus = menuService.buildTreeMenu(menuList);

    HashMap<Object, Object> map = new HashMap<>();
    map.put("authorization", token);
    map.put("menuList", menus);
    map.put("userInfo",one);
    System.out.println("+++++++++++++++");
    return map;
  }

  @Override
  public IPage<Manager> getListWithPage(Page page, String query) {
    return  managerMapper.selectAllWithPage(page,query);

  }

  @Override
  @Transactional
  //保存用户及角色
  public boolean saveUser(Manager manager) {
    int i = managerMapper.insert(manager);
    if(i > 0){
      for (SysRole s : manager.getRoleList())
      {
        managerMapper.saveUser(manager.getManagerId(),s.getId());
      }
    }
    return true;
  }

  @Override
  @Transactional
  public boolean updateUser(Manager manager) {

    managerMapper.updateById(manager);
    Integer i = managerMapper.deleteUserWithRole(manager.getManagerId());
    if(i>0){
      List<SysRole> roleList = manager.getRoleList();
      if(!CollectionUtils.isEmpty(roleList)){
        for (SysRole s : roleList)
        {
          managerMapper.saveUser(manager.getManagerId(),s.getId());
        }
      }

    }
    return true;
  }

  @Transactional
  @Override
  public boolean removeUser(String userId) {
    int i = managerMapper.deleteById(userId);
    if(i>0){
      managerMapper.deleteUserWithRole(userId);
    }
    return true;
  }

  private List<Menu> getMenuList(String username) {

    QueryWrapper<Manager> managerQueryWrapper = new QueryWrapper<>();
    managerQueryWrapper.eq("manager_name", username);
    Manager manager = managerMapper.selectOne(managerQueryWrapper);
    return menuMapper.selectList(new QueryWrapper<Menu>().inSql("id", "select mr.menu_id" +
     " from sys_menu_role mr where mr.role_id in \n" +
     " (select r.id from sys_role r join sys_user_role ur on r.id = ur.role_id" +
     " where ur.user_id = " + manager.getManagerId() + ")").orderByAsc("order_num"));

  }
}
